home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
476-500
/
disk_500
/
wiconify
/
wiconsetter.lzh
/
wInfo2Icon
/
wInfo2Icon.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-19
|
9KB
|
337 lines
/*
* WINFO2ICON A companion utility to wIconSetter and wIconify.
* wInfo2Icon converts a Workbench .info file into
* an icon file usable by wIconSetter.
*
* Copyright 1990 by Davide P. Cervone, all rights reserved.
* You may use this code, provided this copyright notice is kept intact.
*/
#include "wInfo2Icon.h"
static char *program = PROGRAM;
static char *copyright = COPYRIGHT;
struct IconBase *IconBase;
static struct DiskObject *theInfo; /* Data read from the .info file */
static long IconFile; /* the output icon file */
static struct BitMap theBitMap; /* a bitmap for the image */
static struct BitMap theMaskMap; /* a bitmap for the mask image */
static int theWidth,theHeight,theDepth; /* size of the image */
static struct TmpRas theTmpRas; /* needed for FloodFill */
static char *InfoName; /* name of the info file */
static char *IconName; /* name of the icon file */
static char *Hex = "0123456789abcdef)!@#$%^&*(ABCDEF";
#define MAXHEX 32
#define MAXLINE 132
#define BLT_INVERT 0x50
#define FLOOD_SAME 1
/*
* FreePlanes()
*
* Free each bitplane of the bitmap and free the temporary raster.
*/
static void FreePlanes()
{
short i;
for (i=0; i<theDepth; i++)
{
if (theBitMap.Planes[i])
FreeRaster(theBitMap.Planes[i],theWidth,theHeight);
theBitMap.Planes[i] = NULL;
}
if (theTmpRas.RasPtr) FreeRaster(theTmpRas.RasPtr,theWidth,theHeight);
theTmpRas.RasPtr = NULL;
}
/*
* DoExit()
*
* General purpose error-exit routine. Print an error message if one was
* supplied (it can have up to three parameters), and then clean up any
* memory, libraries, etc. that need to be handled before exiting.
*/
void DoExit(s,x1,x2,x3)
char *s, *x1, *x2, *x3;
{
long status = EXIT_OK;
if (s != NULL)
{
printf(s,x1,x2,x3);
printf("\n");
status = EXIT_ERROR;
}
FreePlanes();
if (IconFile) fclose(IconFile);
if (theInfo) FreeDiskObject(theInfo);
if (IntuitionBase) CloseLibrary(IntuitionBase);
if (GfxBase) CloseLibrary(GfxBase);
if (IconBase) CloseLibrary(IconBase);
exit(status);
}
/*
* CheckLibOpen()
*
* Call OpenLibrary() for the specified library, and check that the
* open succeeded.
*/
static void CheckLibOpen(lib,name,rev)
APTR *lib;
char *name;
int rev;
{
extern APTR OpenLibrary();
if ((*lib = OpenLibrary(name,(LONG)rev)) == NULL)
DoExit("Can't open %s",name);
}
/*
* GetPlanes()
*
* Set the size of the image, but add an extra bitplane (for the mask)
* Initialize the BitMaps
* Get the bitplanes for the BitMap
* Make the mask BitMap share the last bitplane
* Get a temporary raster (for FloodFill)
*/
static void GetPlanes(w,h,d)
int w,h,d;
{
short i;
theWidth = w; theHeight = h; theDepth = d+1;
InitBitMap(&theBitMap,theDepth,w,h);
InitBitMap(&theMaskMap,1,w,h);
for (i=0; i<theDepth; i++)
{
theBitMap.Planes[i] = AllocRaster(w,h);
if (theBitMap.Planes[i] == NULL) DoExit("Can't Get BitPlane %d",i);
}
theMaskMap.Planes[0] = theBitMap.Planes[d];
theTmpRas.RasPtr = (UBYTE *)AllocRaster(w,h);
if (theTmpRas.RasPtr == NULL) DoExit("Can't Get TmpRas for FloodFill");
theTmpRas.Size = RASSIZE(theWidth,theHeight);
}
/*
* DoBackFill()
*
* Invert the image's bitmap (so the Mask bitplane becomes all 1's) and flood
* the RastPort with 0's starting at the upper left-hand corner. Since there
* is a one pixel border around the actual image data, this does a flood fill
* from the outside of the image into the interior. The Mask bitplane then
* has 0's exactly outside the image itself.
*/
static void DoBackFill(theRastPort)
struct RastPort *theRastPort;
{
BltBitMap(theRastPort->BitMap,0,0,theRastPort->BitMap,0,0,
theWidth,theHeight,BLT_INVERT,0xFF,NULL);
SetAPen(theRastPort,0L);
SetDrMd(theRastPort,JAM1);
Flood(theRastPort,FLOOD_SAME,0,0);
}
/*
* WriteBitMap()
*
* Clip the width to the maximum we can write
* For each row in the image
* And each column in each row
* Get the pen color of the pixel
* Store the HEX digit in the line buffer
* End the line and print it to the file
*/
static void WriteBitMap(theRastPort,Width,Height,x,y)
struct RastPort *theRastPort;
int Width,Height,x,y;
{
short h,w;
int pen;
char Line[MAXLINE];
if (Width > MAXLINE) Width = MAXLINE;
for (h=0; h<Height; h++)
{
for (w=0; w<Width; w++)
{
pen = ReadPixel(theRastPort,w+x,h+y) % MAXHEX;
Line[w] = Hex[pen];
}
Line[w] = 0;
fprintf(IconFile,"\n ");
fprintf(IconFile,Line);
}
fprintf(IconFile,"\n");
}
/*
* WriteImage()
*
* If there is an image to write,
* Free any bitplanes that we already got
* Get the number of planes we need to write and count the depth
* Get the bitplanes for a slightly larger image (leave a border around it)
* Set up the RastPort to use the BitMap and TmpRas
* Clear the bitmap and temporarily remove the extra bitplane
* Draw the image into the prepared bitmap, leaving a 1-pixel border
* Write the image to the file
* If we are also writing the mask,
* Put back the extra bitplane
* Do the backfill stuff to get the mask
* Write the MASK command
* Use the mask bitmap and write the mask to the file
*/
static void WriteImage(theImage,MaskIt)
struct Image *theImage;
int MaskIt;
{
int depth;
int mask;
struct RastPort theRastPort;
if (theImage)
{
FreePlanes();
mask = theImage->PlanePick | theImage->PlaneOnOff;
for (depth=0; mask; depth++) mask >>= 1;
if (depth > 5) depth = 5;
GetPlanes(theImage->Width+2,theImage->Height+2,depth);
InitRastPort(&theRastPort);
theRastPort.BitMap = &theBitMap;
theRastPort.TmpRas = &theTmpRas;
SetRast(&theRastPort,0L); theBitMap.Depth--;
DrawImage(&theRastPort,theImage,1,1);
WriteBitMap(&theRastPort,theImage->Width,theImage->Height,1,1);
if (MaskIt)
{
theBitMap.Depth++;
DoBackFill(&theRastPort);
fprintf(IconFile,"\nMASK:\n");
theRastPort.BitMap = &theMaskMap;
WriteBitMap(&theRastPort,theImage->Width,theImage->Height,1,1);
}
}
}
/*
* WriteIcon()
*
* Get the WB icon's Gadget structure
* Write the identification header to the file
* If the gadget has an image,
* Write the IMAGE command to the file
* Write the image itself, and write the mask if it is a BACKFILL icon
* Now check the highlight bits:
* GADGHIMAGE:
* If there is a select image,
* Write the SELECT command, and write the image data and mask
* GADGHNONE:
* If the gadget had an image,
* Write it as the select image (this way it looks the same selected
* as unselected) and write the mask as well, for good measure
* (the WB doesn't do this, but we will, since it's easy)
* Don't write anything else for the other highlight types
* (we've already taken care of GADGHBACKFILL, and GADGHCOMP is the
* default function of wIconify).
*/
static void WriteIcon()
{
struct Gadget *theGadget = &(theInfo->do_Gadget);
fprintf(IconFile,"/*\n * %s\n *\n",IconName);
fprintf(IconFile," * An Icon created by %s\n",program);
fprintf(IconFile," * From the Workbench icon %s.info\n",InfoName);
fprintf(IconFile," */\n");
if ((theGadget->Flags & GADGIMAGE) && theGadget->GadgetRender)
{
fprintf(IconFile,"\nIMAGE:\n");
WriteImage(theGadget->GadgetRender,
(theGadget->Flags & GADGHIGHBITS) == GADGBACKFILL);
}
switch(theGadget->Flags & GADGHIGHBITS)
{
case GADGHIMAGE:
if (theGadget->SelectRender)
{
fprintf(IconFile,"\nSELECT:\n");
WriteImage(theGadget->SelectRender,TRUE);
}
break;
case GADGHNONE:
if ((theGadget->Flags & GADGIMAGE) && theGadget->GadgetRender)
{
fprintf(IconFile,"\nSELECT:\n");
WriteImage(theGadget->GadgetRender,TRUE);
}
break;
case GADGBACKFILL:
case GADGHCOMP:
break;
}
}
/*
* main()
*
* If run from the WB, sinply exit
* Show the usage if there are not the right number of arguments
* Otherwise, get the file names
* Open the needed libraries
* Get the info from the .info file, if possible
* Open the icon file for writing, if possible
* Write the icon to the file
*/
void main(argc,argv)
int argc;
char **argv;
{
if (argc == 0) DoExit(NULL);
if (argc != 3) DoExit("Usage: %s",USAGE);
InfoName = argv[1];
IconName = argv[2];
CheckLibOpen(&IntuitionBase,"intuition.library",INTUITION_REV);
CheckLibOpen(&GfxBase,"graphics.library",GRAPHICS_REV);
CheckLibOpen(&IconBase,"icon.library",ICON_REV);
theInfo = GetDiskObject(InfoName);
if (theInfo == NULL) DoExit("Can't read Info file '%s.info'",InfoName);
IconFile = fopen(IconName,"w");
if (IconFile == NULL) DoExit("Can't write Icon file '%s'",IconName);
WriteIcon();
DoExit(NULL);
}